﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using QLTT.Models;
using QLTT.Commands;
using System.Windows.Input;
using System.Text.RegularExpressions;
using QLTT.Properties;

namespace QLTT.ViewModels
{
    public enum UserRole
    {
        Unauthorized = 0,
        NormalUser = 1,
        Administrator = 2
    }
    class UserViewModel : WorkspaceViewModel, System.ComponentModel.IDataErrorInfo
    {
        private User _user;
        private string _role;
        private string[] _roles;
        private icanDataContext _dataContext;
        private DelegateCommand _saveCommand;
        private DelegateCommand _editCommand;
        private DelegateCommand _cancelCommand;

        private bool _isSelected;
        public UserViewModel(icanDataContext dataContext)
        {
            _dataContext = dataContext;
            _user = new User();
            _user.Role = (short)UserRole.NormalUser;
            _role = Properties.Resources.Role_NormalUser;
            base.DisplayName = Properties.Resources.Base_DisplayName_User_New;
        }

        public UserViewModel(icanDataContext dataContext, User user)
        {
            _user = user;
            _dataContext = dataContext;
            if (_user.Role == (short)UserRole.Administrator)
            {
                _role = Properties.Resources.Role_Administrator;
            }
            else
                _role = Properties.Resources.Role_NormalUser;
            base.DisplayName = Properties.Resources.Base_DisplayName_User_Edit;
        }
        public ICommand SaveCommand
        {
            get
            {
                if (_saveCommand == null)
                {
                    _saveCommand = new DelegateCommand(Save);
                }
                return _saveCommand;
            }
        }
        public ICommand EditCommand
        {
            get
            {
                if (_editCommand == null)
                {
                    _editCommand = new DelegateCommand(Edit);
                }
                return _editCommand;
            }
        }
        public ICommand CancelCommand
        {
            get
            {
                if (_cancelCommand == null)
                {
                    _cancelCommand = new DelegateCommand(Cancel);
                }
                return _cancelCommand;
            }
        }

        private void Save()
        {
            try
            {
                if (_dataContext == null || _user == null)
                    return;
                string[] properties = { "UserName", "Password", "Password2", "Name", "Role" };
                if (!ValidateData(properties))
                    return;
                bool isInsert = _user.ID == 0;
                if (isInsert)
                {
                    _dataContext.Users.InsertOnSubmit(_user);
                }
                _dataContext.SubmitChanges();
                if (isInsert)
                    Mediator.NotifyColleagues<User>(Messages.ListUserUpdated, _user);
                Mediator.NotifyColleagues<WorkspaceViewModel>(Messages.WorkspaceRemove, this);
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("Application", ex.ToString(), System.Diagnostics.EventLogEntryType.Error);
            }

        }
        private void Edit()
        {
            if (_dataContext == null || _user == null)
                return;

            Mediator.NotifyColleagues<WorkspaceViewModel>(Messages.WorkspaceAdd, this);
        }
        private void Cancel()
        {
            if (_user.ID > 0)
                _dataContext.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, _user);
            Mediator.NotifyColleagues<WorkspaceViewModel>(Messages.WorkspaceRemove, this);
        }
        public void Delete()
        {
            if (_dataContext == null || _user == null)
                return;
            try
            {
                _dataContext.Users.DeleteOnSubmit(_user);
                _dataContext.SubmitChanges();
            }
            catch (Exception ex)
            {
                System.Diagnostics.EventLog.WriteEntry("Application", ex.ToString(), System.Diagnostics.EventLogEntryType.Error);
            }
        }
        public bool CanDelete
        {
            get { return true; }
        }
        public long ID
        {
            get { return _user.ID; }
        }

        public string Name
        {
            get { return _user.Name; }
            set
            {
                if (_user.Name == value) return;
                _user.Name = value;
                base.OnPropertyChanged("Name");
            }
        }
        public string UserName
        {
            get { return _user.UserName; }
            set
            {
                if (_user.UserName == value) return;
                _user.UserName = value;
                base.OnPropertyChanged("UserName");
            }
        }
        public string Password
        {
            get { return string.Empty; }
            set
            {
                if(string.IsNullOrEmpty(value))
                    return;
                string pass = Utils.CreateMD5Hash(value);
                if (_user.Password ==  pass) return;
                _user.Password = pass;
                base.OnPropertyChanged("Password");
            }
        }
        public string Password2 { get; set; }
        public string Role
        {
            get { return _role; }
            set
            {
                if (value == Properties.Resources.Role_Administrator)
                    _user.Role = (short)UserRole.Administrator;
                else
                    _user.Role = (short)UserRole.NormalUser;
                base.OnPropertyChanged("Role");
            }
        }
        public string[] Roles
        {
            get
            {
                if (_roles == null)
                {
                    _roles = new string[]{
                        Properties.Resources.Role_NormalUser,
                        Properties.Resources.Role_Administrator
                    };
                }
                return _roles;
            }
        }
        public System.Windows.Visibility NoteVisibility
        {
            get
            {
                if (_user.ID > 0)
                    return System.Windows.Visibility.Visible;
                return System.Windows.Visibility.Hidden;
            }
        }

        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value == _isSelected)
                    return;

                _isSelected = value;

                base.OnPropertyChanged("IsSelected");
            }
        }
        #region IDataErrorInfo Members

        public string Error
        {
            get { return null; }
        }

        public string this[string property]
        {
            get
            {
                string msg = null;
                switch (property)
                {
                    case "Name":
                        if (string.IsNullOrEmpty(this.Name))
                            msg = Resources.ValidationUserName_Error;
                        break;
                    case "UserName":
                        Regex rgx = new Regex("[a-z\\d]{8,}", RegexOptions.IgnoreCase);
                        if (string.IsNullOrEmpty(this.UserName) || !rgx.IsMatch(this.UserName))
                            msg = Resources.ValidationUserUserName_Error;
                        break;
                    case "Password":
                        if (this.ID==0 && string.IsNullOrEmpty(this.Password))
                            msg = Resources.ValidationUserPassword_Error;
                        break;
                    case "Password2":
                        if (this.Password2 != this.Password)
                            msg = Resources.ValidationUserPassword2_Error;
                        break;
                    default:
                        throw new ArgumentException(
                            Resources.ValidationDefaultException_Error + property);
                }
                return msg;
            }
        }

        #endregion // IDataErrorInfo Members

    }
}
